package org.copper.utils
{
	/**
	 * Utility for common string operations.
	 * */
	public final class StringUtils
	{
		/**
		 * Sorts strings by similarity to given string.
		 * */
		public static function sortStringVectorLcs(vector:Vector.<String>, sortBy:String, reversed:Boolean = false):Vector.<String>
		{
			if (isNullOrEmpty(sortBy))
				return vector;
			
			if (reversed)
			{
				vector.sort(function(a:String, b:String):int
				{
					if (LCSutility.compareStrings(a, sortBy) > LCSutility.compareStrings(b, sortBy))
						return 1;
					else
						return -1;
				});
			}
			else
			{
				vector.sort(function(a:String, b:String):int
				{
					if (LCSutility.compareStrings(a, sortBy) > LCSutility.compareStrings(b, sortBy))
						return -1;
					else
						return 1;
				});
			}
			return vector;
		}
		
		/**
		 * Creates clone of given string.
		 * Used to unlink the cloned string from its source,
		 * for source to be garbage collected.
		 * 
		 * For instance - saving a string from an XML object directly will prevent 
		 * garbage collector to collect entire XML.
		 * In that case you should use this method.
		 * */
		public static function copyString(str:Object):String
		{
			const string:String = (str is String)?String(str):str.toString();
			return ("_" + string).substr(1, string.length); 
		}
		
		/**
		 * Sorts strings by similarity to given string.
		 * */
		public static function sortStringArrayLcs(array:Array, sortBy:String, reversed:Boolean = false):Array
		{
			const vec:Vector.<String> = new Vector.<String>();
			const len:uint = array.length;
			vec.length = len;
			vec.fixed = true;
			
			var i:uint = 0;
			for(; i < len; i++) vec[i] = array[i];
			
			sortStringVectorLcs(vec, sortBy, reversed);
			
			for(i = 0; i < len; i++) array[i] = vec[i];
			
			return array;
		}
		
		public static function isNullOrEmpty(str:String):Boolean
		{
			if (str == null)
				return true;
			
			if (str.length < 1)
				return true;
			
			return false;
		}
		
		public static function emptyOrHasOnlySpaces(str:String):Boolean
		{
			if (isNullOrEmpty(str))
				return true;
			
			const len:int = str.length;
			
			for (var i:int = 0; i < len; i++)
				if (str.charAt(i) != " ")
					return false;
			
			return true;
		}
		
		/**
		 * This method simply limks to 'LCSutility.compareStrings' method.
		 * 
		 * Calculates percentage of difference between 2 given strings.
		 * Returned number between 0 and 1.
		 * 0 - if strings are equal.
		 * 1 - if strings are completely different.
		 */
		public static function stringsDistinction(a:String, b:String):Number
		{
			return LCSutility.compareStrings(a, b);
		}
		
		/**
		 * Pretifies readble texts.
		 * Removes duplicated spaces or commas, and ensures a space after a comma.
		 * */
		public static function trim(str:String):String
		{
			if (str == null)
				return "";
			
			var result:String;
			var vector:Vector.<String> = new Vector.<String>();
			var array:Array = str.split(" ");
			var len:uint = array.length;
			var i:uint = 0;
			var token:String;
			
			for(; i < len; i++)
			{
				token = array[i];
				if (token.length > 0)
					vector.push(token);
			}
			
			result = vector.join(" ");
			vector = new Vector.<String>();
			array = result.split(",");
			len = array.length;
			
			for(i = 0; i < len; i++)
			{
				token = array[i];
				if (emptyOrHasOnlySpaces(token) == false)
					vector.push(token);
			}
			
			result = vector.join(", ");
			
			return result;
		}
	}
}